package pictogram.front;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;


import pictogram.effects.Chocolate;
import pictogram.effects.ClearScene;
import pictogram.effects.Dirty;
import pictogram.effects.Esmerald;
import pictogram.effects.Hallo;
import pictogram.effects.HeavyBlush;
import pictogram.effects.MiddleRaw;
import pictogram.effects.SmoothBlue;
import pictogram.effects.SmoothBlush;
import pictogram.effects.SmoothIce;
import pictogram.effects.SmoothIndian;
import pictogram.effects.SmoothYellow;
import pictogram.effects.BrightRaw;
import pictogram.effects.HistParent;
import pictogram.effects.SmoothGreen;

public class Pictogram extends FragmentActivity
		implements LeftFragment.OnItemSelectedListener, RightFragment.OnItemSelectedListener
{
		
	Bitmap bmTemp = null;
	boolean changedPic = false;
	private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1001;
	final int PIC_CROP = 2;
	public static final int MEDIA_TYPE_IMAGE = 1;
	private Uri fileUri;
	
	Uri selectedImage;
	MiddleFragment middleImageView;		
	ImageView imageView;
	
	boolean bCameraOnce ;
	
	private float rotation = 0;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
				
		setContentView(R.layout.activity_pictogram);
		
		bCameraOnce = false;
		middleImageView =(MiddleFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentMiddle);
		middleImageView.setImage(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
		
		imageView = (ImageView) middleImageView.getView().findViewById(R.id.imageViewMiddle);
			
		//routive to open the cam and save the image
		if(!bCameraOnce)
		{
			Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
			fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
			intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
			intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, "landscape");	
			startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
		}
	 
	}
	
	protected void onSaveInstanceState(Bundle outState)
	{
		super.onSaveInstanceState(outState);
		
		bCameraOnce = true;
		outState.putBoolean("cameraEntry", bCameraOnce);
		
	}
	
	public void onRestoreInstanceState(Bundle savedInstanceState)
	{
		super.onRestoreInstanceState(savedInstanceState);
		
		bCameraOnce = savedInstanceState.getBoolean("cameraEntry");
		
	}
	
	//that's the uri to save the image
		private static Uri getOutputMediaFileUri(int type)
		{
			return Uri.fromFile(getOutputMediaFile(type));
		}
		
		private static File getOutputMediaFile(int type)
		{
			File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
					Environment.DIRECTORY_PICTURES), "Pictogram");
			
			//checking if the directory exists
			if(!mediaStorageDir.exists())
			{
				if(! mediaStorageDir.mkdirs())
				{
					return null;
				}
			}	
			//create a media file name
			String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
			File mediaFile;
			if(type == MEDIA_TYPE_IMAGE)
			{
				mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
			}
			else
			{
				return null;
			}
			return mediaFile;
		}
	
	public Bitmap shrinkBitmap(String file, int width, int height)
	 {
		   
	     BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
	        bmpFactoryOptions.inJustDecodeBounds = true;
	        bmpFactoryOptions.inMutable=true;
	        
	        Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
	       
	        int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
	        int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
	         
	        if (heightRatio > 1 || widthRatio > 1)
	        {
	         if (heightRatio > widthRatio)
	         {
	          bmpFactoryOptions.inSampleSize = heightRatio;
	         } else {
	          bmpFactoryOptions.inSampleSize = widthRatio;
	         }
	        }
	         
	        bmpFactoryOptions.inJustDecodeBounds = false;
	        bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
	     return bitmap;
	    }

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.pictogram, menu);
		return true;
	}

	@Override
	public void onMainItemSelected(int option) {
		// TODO Auto-generated method stub
				
		if (option==0) //BrightRaw
		{
			BrightRaw brightRaw = new BrightRaw();
			histogramMatchingByLoadedPicture(brightRaw);
		}
		
		if (option==1) //SmoothGreen
		{ 
			SmoothGreen smoothGreen = new SmoothGreen();
			histogramMatchingByLoadedPicture(smoothGreen);
		}
		
		if(option==2)
		{
			SmoothYellow smoothYellow = new SmoothYellow();
			histogramMatchingByLoadedPicture(smoothYellow);
		}
		
		if(option==3)
		{
			SmoothBlue smoothBlue = new SmoothBlue();
			histogramMatchingByLoadedPicture(smoothBlue);
		}
		
		if(option==4)
		{
			Hallo hallo = new Hallo();
			histogramMatchingByLoadedPicture(hallo);
		}
		
		if(option==5)
		{
			MiddleRaw middleRaw = new MiddleRaw();
			histogramMatchingByLoadedPicture(middleRaw);
		}
		
		if(option==6)
		{
			SmoothIce smoothIce = new SmoothIce();
			histogramMatchingByLoadedPicture(smoothIce);
		}
		
		if(option==7)
		{
			SmoothBlush smoothBlush = new SmoothBlush();
			histogramMatchingByLoadedPicture(smoothBlush);
		}
		
		if(option==8)
		{
			HeavyBlush heavyBlush = new HeavyBlush();
			histogramMatchingByLoadedPicture(heavyBlush);
		}
		
		if(option==9)
		{
			SmoothIndian smoothIndian = new SmoothIndian();
			histogramMatchingByLoadedPicture(smoothIndian);
		}
		
		if(option==10)
		{
			Dirty dirty = new Dirty();
			histogramMatchingByLoadedPicture(dirty);
		}
		
		if(option==11)
		{
			Esmerald esmerald = new Esmerald();
			histogramMatchingByLoadedPicture(esmerald);
		}
		
		if(option==12)
		{
			ClearScene clearScene = new ClearScene();
			histogramMatchingByLoadedPicture(clearScene);
		}
		
		if(option==13)
		{
			Chocolate choc = new Chocolate();
			histogramMatchingByLoadedPicture(choc);
		}	
	}
	
	public void setPictureOnBackground(Bitmap bm)
	{
		//ImageViewFragment imageViewFragment = (ImageViewFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentImageView);
		if(middleImageView != null & middleImageView.isInLayout())
		{
			middleImageView.setImage(bm);
		}
	}
				
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		super.onActivityResult(requestCode, resultCode, data);		
		setResult(resultCode, data);
			
		if(resultCode == 0)
		{
			finish();
		}		
		if(resultCode == RESULT_OK)
		{
			if(requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE)
			{			
				
				bmTemp = shrinkBitmap(fileUri.getPath().toString(),960, 1280);
					setPictureOnBackground(bmTemp);
			}
			
		}	
	}
	
	public Uri saveTheOperatedImage()
	{
		
		OutputStream fOut = null;
	    Uri outputFileUri = null;
	     try {
	    File root = new File(Environment.getExternalStorageDirectory()
	      + File.separator + "Pictogram" + File.separator);
	    root.mkdirs();
	   String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
	   File sdImageMainDirectory = new File(root, "Pictogram"+timeStamp+".png");
	   
	    outputFileUri = Uri.fromFile(sdImageMainDirectory);
	    fOut = new FileOutputStream(sdImageMainDirectory);
	   } catch (Exception e) {
	    Toast.makeText(this, "Error occured. Please try again later.",
	      Toast.LENGTH_SHORT).show();
	   }

	   try {
	    im.compress(Bitmap.CompressFormat.PNG, 100, fOut);
	    fOut.flush();
	    fOut.close();
	   } catch (Exception e) {
	   }
	   
	   return outputFileUri;
		
	}

	@Override
	public void onButtonSelected(String option) {
		// TODO Auto-generated method stub
		if(option.equals("Ok"))
		{	
			//saveTheOperatedImage();
			
		     changedPic = false;
			 final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
			 emailIntent.setType("image/png");
		     //emailIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
			 emailIntent.putExtra(Intent.EXTRA_STREAM, saveTheOperatedImage());
		     startActivity(Intent.createChooser(emailIntent, "Share "));
		}
		
		if( option.equals("Cancel") && changedPic)
		{
			changedPic = false;
			setPictureOnBackground(bmTemp);
		} else if(option.equals("Cancel") && !changedPic)
		{
			finish();
		}
		
		if(option.equals("Turn"))
		{
			rotation = rotation + 90;
			
			imageView.setRotation(rotation);
			//needs to re save the option
		}
	}
	
	private Bitmap im;	
	
	private void histogramMatchingByLoadedPicture(HistParent test)
	{
		//indicating the modified the picture to select the option in the cancel button
		changedPic = true; 
		
		final int WT = bmTemp.getWidth();
		final int HT = bmTemp.getHeight();
		
		//loading in an internal picture to be able to modify
		im = Bitmap.createBitmap(bmTemp.getWidth(), bmTemp.getHeight(), Bitmap.Config.ARGB_8888);	
		Canvas c = new Canvas(im);
		c.drawBitmap(bmTemp, 0, 0, new Paint());

		flipit();	
		//turning flat the histogram of the picture taken
		//--------------------------------------HISTOGRAM EQUALIZATION
		//mouting the initial histogram
		final int LEVEL = 256;
		
		int [] nred = new int[LEVEL];
		int [] ngreen = new int[LEVEL];
		int [] nblue = new int[LEVEL];
		
		double [] pr = new double[LEVEL];
		double [] pg = new double[LEVEL];
		double [] pb = new double[LEVEL];
		
		double [] sr = new double[LEVEL];
		double [] sg = new double[LEVEL];
		double [] sb = new double[LEVEL];
		
		for(int h=0; h < im.getHeight(); h++)
		{
			for(int w=0; w<im.getWidth(); w++)
			{
				int red = 0xff&(im.getPixel(w, h)>>16);
				int green = 0xff&(im.getPixel(w, h)>>8);
				int blue = 0xff&(im.getPixel(w, h));
				
				nred[red]++;
				ngreen[green]++;
				nblue[blue]++;		
			}//w
		}//h
		
		//PDF
		for(int l=0; l<LEVEL; l++)
		{
			pr[l] = (double)nred[l]/((double)HT*(double)WT);
			pg[l] = (double)ngreen[l]/((double)HT*(double)WT);
			pb[l] = (double)nblue[l]/((double)HT*(double)WT);
		}
		
		//mapping the domain from r to s
		for(int l=0; l<LEVEL; l++)
		{
			//mapping the red color
			sr[l]=0;
			for(int j=0; j<l; j++)
			{
				sr[l] = sr[l]+pr[j];
			}
			sr[l] = (LEVEL-1)*(sr[l]);
			
			//mapping the green color
			sg[l]=0;
			for(int j=0; j<l; j++)
			{
				sg[l] = sg[l]+pg[j];
			}
			sg[l] = (LEVEL-1)*(sg[l]);
			
			//mapping the blue color
			sb[l]=0;
			for(int j=0; j<l; j++)
			{
				sb[l] = sb[l]+pb[j];
			}
			sb[l] = (LEVEL-1)*(sb[l]);
			
		}//l		
		//SECOND IMAGEM TO BE USED BY HISTOGRAM SPECIFICATION
		for(int l=0; l < LEVEL; l++)
        {
            nred[l]=0;
            ngreen[l]=0;
            nblue[l]=0;
        }		
		//Teste test = new Teste();
		           
        //digital levels so round the values
         for(int h=0; h<LEVEL; h++)
         {
             sr[h] = Math.round(sr[h]);
             sg[h] = Math.round(sg[h]);
             sb[h] = Math.round(sb[h]);    
         }
         
       //scanning between s and G to look each one is similar and 
         //remaping the index
         for(int l=0; l<LEVEL; l++)
         {
             double temp = 0.0;
             double [] smallg = new double[2];
             double [] smallr = new double[2];
             double [] smallb = new double[2];
             
             smallg[0] = 0;
             smallg[1] =10;
             
             smallr[0] =0;
             smallr[1] =10;
             
             smallb[0] =0;
             smallb[1] =10;
             
             for(int z=0; z<LEVEL; z++)
             {
                 temp = Math.abs(sr[l] - test.gzr(z));
                 if(temp<smallr[1])
                 {
                     smallr[1] = temp;
                     smallr[0] = z;
                 }
                 
                 temp = Math.abs(sg[l] - test.gzg(z));
                 if(temp<smallg[1])
                 {
                     smallg[1] = temp;
                     smallg[0] = z;
                 }
                 
                 temp = Math.abs(sb[l] - test.gzb(z));
                 if(temp<smallb[1])
                 {
                     smallb[1] = temp;
                     smallb[0] = z;
                 }
             }//z
             //re-mapping
             sr[l] = smallr[0];
             sg[l] = smallg[0];
             sb[l] = smallb[0];
         }
         
              
         for(int h=0; h<im.getHeight(); h++)
         //for(int h=h0; h < hf; h++)
         {
             for(int w=0; w<im.getWidth(); w++)
        	 //for(int w=w0; w < wf; w++)
             {
                 int pix=0;
                 int alpha = 0xff & (im.getPixel(w, h)>>24);
                 int red =   0xff & (im.getPixel(w, h)>>16);
                 int green = 0xff & (im.getPixel(w, h)>>8);
                 int blue =  0xff & im.getPixel(w, h);
                 
                 red = (int) sr[(int)red];
                 green = (int) sg[(int)green];
                 blue = (int) sb[(int)blue];
                 
                 pix = pix | blue;
                 pix = pix | (green <<8);
                 pix = pix | (red <<16);
                 pix = pix | (alpha <<24);
                 
                 im.setPixel( w, h, pix);
                 pix = 0; 
             }
         }
         
         //titleView.setText("Pictogram");
         setPictureOnBackground(im);  
	}
	
	private Interpolator accelerator = new AccelerateInterpolator();
	private Interpolator decelerator = new DecelerateInterpolator();
	
	private void flipit() {
       final ImageView imageViewVisible;
       imageViewVisible = imageView;
       
       ObjectAnimator visToInvis = ObjectAnimator.ofFloat(imageViewVisible, "rotationY", 0f, 90f);
       visToInvis.setDuration(500);
       visToInvis.setInterpolator(accelerator);
       final ObjectAnimator invisToVis = ObjectAnimator.ofFloat(imageViewVisible, "rotationY",
               -90f, 0f);
       invisToVis.setDuration(500);
       invisToVis.setInterpolator(decelerator);
       visToInvis.addListener(new AnimatorListenerAdapter() {
           @Override
           public void onAnimationEnd(Animator anim) {
           	imageViewVisible.setVisibility(View.GONE);
               invisToVis.start();
               imageViewVisible.setVisibility(View.VISIBLE);
           }
       });
       visToInvis.start();
   }
}
